#include "FreshNet.h"

#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <list>
#include <vector>

#include "Database.h"
#include "Query.h"

using namespace std;

void
 FreshNet::visitLink(string url)
{
    int status;
    pid_t child = fork();

    switch (child) {
    case -1:
	cerr << "Error spawning child process" << endl;
	break;
    case 0:
	execlp("links", "links", url.data(), NULL);
	cerr << "error exec-ing" << endl;
	break;
    default:
	waitpid(child, &status, 0);
	break;

    }
}

FreshNet::FreshNet(string dbFile):db(initDatabase(dbFile).data())
{
}

string FreshNet::initDatabase(string dbFile)
{
    ifstream in;
    in.open(dbFile.data());
    in.close();
    if (in.fail()) {
	in.clear(ios::failbit);

	ofstream dbo;
	dbo.open(dbFile.data());
	dbo.close();

	Database db(dbFile);
	Query q(db);

	q.execute("create table [Feeds] ( \
			feedUrl string PRIMARY KEY, \
			title string, \
			author string, \
			description string, \
			pageUrl string \
			)");

	q.execute("create table [Posts] ( \
            url string PRIMARY KEY, \
            feedUrl string, \
			title string, \
			author string, \
			description string, \
            content string \
            )");
    }

    return dbFile;
}

string tosql(string s)
{
    char* data = (char*)s.data();
    for(unsigned int i = 0; i < s.size(); i++)
        if(data[i] == '\'')
            data[i] = '`';
    
    return s;
} 

void FreshNet::printUsage()
{
    cout << "This is not how to tie a knot!" << endl;
}

bool FreshNet::containsFeed(string feedUrl)
{
    Query q(db);
    
    string query("SELECT COUNT(*) FROM [Feeds] WHERE feedUrl = '");
    query.append(tosql(feedUrl)).append("'");
            
    return q.get_count(query) > 0;
}

void FreshNet::addFeed(Feed & feed)
{
    Query q(db);

	string query = "INSERT INTO [Feeds](title, author, description, feedUrl, pageUrl) VALUES( \
		'" + tosql(feed.getTitle()) + "', " +
    	"'" + tosql(feed.getAuthor()) + "', " + 
        "'" + tosql(feed.getDescription()) + "', " + 
        "'" + tosql(feed.getFeedUrl()) + "', " +
        "'" + tosql(feed.getPageUrl()) + "')";
    
    q.execute(query);
    
    vector<Post> posts = feed.getPosts();
    for(vector<Post>::iterator i = posts.begin(); i != posts.end(); i++)
    {
        Post& post = *i;
        query = "INSERT INTO [Posts](url, feedUrl, title, author, description, content) VALUES ( \
        '" + tosql(post.link) + "', " +
        "'" + tosql(feed.getFeedUrl()) + "', " +
        "'" + tosql(post.title) + "', " +
        "'" + tosql(post.author) + "', " +
        "'" + tosql(post.description) + "', " +
        "'" + tosql(post.content) + "')";
        
        q.execute(query);
    }    
}

void FreshNet::removeFeed(string feed)
{
    Query q(db);
    
    string query = "DELETE FROM [Posts] WHERE feedUrl = '";
    query.append(tosql(feed)).append("'");
    q.execute(query);
    
    query = "DELETE FROM [Feeds] WHERE feedUrl = '";
    query.append(tosql(feed)).append("'");
    q.execute(query);
}


vector < Feed > FreshNet::getFeeds()
{
    vector < Feed > feeds;

    Query q(db);
    q.get_result
	("SELECT title, author, description, feedUrl, pageUrl FROM [Feeds]");

    while (q.fetch_row()) {
    	DbFeed feed(db, q);
    	feeds.push_back(feed);    
    }

    return feeds;
}
